//
//  LSPublishViewController.swift
//  新浪微博---01次
//
//  Created by 李宗帅 on 16/5/12.
//  Copyright © 2016年 LS. All rights reserved.
//

import UIKit
import SVProgressHUD
import AFNetworking
let holder = "一场白雪..."
let chooseViewMargin: CGFloat = 10
class LSPublishViewController: UIViewController ,UITextViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        view.backgroundColor = UIColor.redColor()
        
        setupNav()
        
        setupTextView()
        
        setupToolBar()
        
        
        //点击TextView的时候 也就是键盘弹出来的时候 通知
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "changeToolBarFrame:", name: UIKeyboardWillChangeFrameNotification, object: nil)
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "showEmoticon:", name: kNotificationEmoticonTransform, object: nil)
        
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "deleteEmoticon:", name: kNotificationEmoticonBack, object: nil)
    }
    
    //控制器的生命周期
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        
        textView.resignFirstResponder()
    }
    
    private func setupNav(){
        
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "返回", style: UIBarButtonItemStyle.Plain, target: self, action: "dismiss")
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "发布", style: UIBarButtonItemStyle.Plain, target: self, action: "publish")
        navigationItem.rightBarButtonItem?.enabled = false
        
        //
        //        navigationItem.title = "发布微博\n换行了吗?" \n 是可以换行的
        
        let label = UILabel(frame: CGRectMake(0, 0, 200, 44))
        
        let str = "发布微博\n谁的微博?"
        
        label.numberOfLines = 0
        
        label.textAlignment = .Center
        
        // NSMutableAttributedString -- 可变的
        // NSAttributedString -- 不可变
        // 需要修改字体和大小，需要用可变的
        let attribute = NSMutableAttributedString(string: str)
        
        // 添加属性 -- 记住一个属性，就找到其他的所有属性了 NSFontAttributeName
        attribute.addAttributes([NSFontAttributeName:UIFont.systemFontOfSize(15),NSForegroundColorAttributeName: UIColor.blackColor()], range: NSMakeRange(0, 4))
        
        attribute.addAttributes([NSFontAttributeName: UIFont.systemFontOfSize(12),NSForegroundColorAttributeName: UIColor.orangeColor()], range: NSMakeRange(5, str.characters.count - 5))
        
        label.attributedText = attribute
        
        navigationItem.titleView = label
    }
    
    
    private func setupTextView(){
        
        view.addSubview(textView)
        
        textView.font = UIFont.systemFontOfSize(16)
        
        textView.holdString = holder
        
        textView.delegate = self
        
        textView.snp_makeConstraints { (make) -> Void in
            make.edges.equalTo(view.snp_edges)
        }
        
        // 通知   
        //当TextView拖拽的时候  uitextView 或者UITextFiele 和键盘相关的 都可以.keyboard开头
        
        //拖拽的时候让键盘消失   只设置onDarg是不行的
        
        textView.keyboardDismissMode = .OnDrag
        
        //设置一下  textView的滚动方向
        textView.alwaysBounceVertical = true
        
        //把选择图片视图添加到TextView中
        textView.addSubview(chooseView)
        
        //设置约束
        chooseView.snp_makeConstraints { (make) -> Void in
            make.left.equalTo(textView.snp_left).offset(chooseViewMargin)
            
            make.top.equalTo(textView.snp_top).offset(100)
            
            make.width.equalTo(kUIScreenW - 2 * chooseViewMargin)
            
            make.height.equalTo(chooseView.snp_width)
        }
        
    }
    
    //发布微博的方法
    @objc private func publish(){
        
        if chooseView.getImages().count > 0 {
            
            upLoad()
        } else {
            update()
        }
        
        
    }
    
    //文字表情微博的发布
    private func update(){
        
        let url = "https://api.weibo.com/2/statuses/update.json"
        
        guard let token = LSOauthViewModel.shareInstance.access_token else {
            return
        }
        
        let param = ["access_token":token,
            "status":textView.getPublishText()
        ]
        
        
        LSHTTPClicent.shareInstance.request(.POST, URLString: url, parameters: param, success: { (_, JSON) -> Void in
            SVProgressHUD.showInfoWithStatus("发布成功")
            }) { (_, error) -> Void in
                SVProgressHUD.showErrorWithStatus(error.description)
        }
    }
    //图片微博的发布
    private func upLoad(){
        let url = "https://upload.api.weibo.com/2/statuses/upload.json"
        
        // 上传图片的时候 , 以form表单的形式上传
        let afn = AFHTTPSessionManager()
        
        // 参数
        
        /*
        false	string	采用OAuth授权方式为必填参数，其他授权方式不需要此参数，OAuth授权后获得。
        status	true	string	要发布的微博文本内容，必须做URLencode，内容不超过140个汉字。
        pic要拼接在formdata表单上
        pic	true	binary	要上传的图片，仅支持JPEG、GIF、PNG格式，图片大小小于5M。
        */
        guard let token = LSOauthViewModel.shareInstance.access_token else {
            //             fatalError("你没有登录")
            return
        }
        
        let  param = ["access_token":token,
            "status": textView.getPublishText()
        ]
        
        let image = chooseView.getImages().first
        // 需要把 UIImage 转换成 NSData
        // UIImageJPEGRepresentation 参数
        // 第二个参数: 系统的压缩比例. 压缩比例,并没有明确的规定
        // 这个系数怎么来呢? 可以和后台沟通,调试.
        let data = UIImageJPEGRepresentation(image!, 0.5)
        // 对图片的压缩除了这个方法.还可以重绘
        
        /*
        url在请求头里 以POST形式 上传的参数在请求体里
        
        */
        // 一会将一下 请求头和请求体
        afn.POST(url, parameters: param, constructingBodyWithBlock: { (form) -> Void in
            // 这个东西就是form 表单
            // form 类似于字典
            /*
            appendPartWithFileData 有四个参数
            第一个参数: 要上传的图片或者视频或者文件的 二进制
            第二个参数: 接口文档的参数
            第三个参数: 上传的文件名(这个可以随意)
            第四个参数: mineType
            */
            
            form.appendPartWithFileData(data!, name: "pic", fileName: "test", mimeType: "image/jpeg")
            
            }, progress: nil, success: { (_ , JSON) -> Void in
                SVProgressHUD.showSuccessWithStatus("图片发布成功")
            }) { (_ , error) -> Void in
                SVProgressHUD.showErrorWithStatus(error.description)
        }
        
        /*
        在实际企业开发过程中,上传图片有2种形式
        第一种: 现在所说的 以表单的形式上传(或者说 二进制流)
        第二种: 把图片,以Base64的形式转码成 String,放在请求体里,进行上传
        
        */

    }
//    //获取发布微博的表情
//     private func getPublishText()->String{
//        
//        /**
//        第一个参数: range:要遍历的长度
//        第二个参数: 默认值
//        第三个参数:闭包回调
//        1.字典
//        2.range
//        3.
//        */
//        
//        var publishText = ""
//        textView.attributedText.enumerateAttributesInRange(NSMakeRange(0, textView.attributedText.length), options: []) { (data:[String :AnyObject], range:NSRange, _) -> Void in
//            
//            //通过打印(data和range)的结果,可以得出结论
//            //如果data这个字典里有NSAttachment 我们暂时认为是表情
//            if let attachment = data["NSAttachment"] as? LSTextAttachment {
//                //表情
//                if let chs = attachment.emoticon?.chs {
//                    publishText = publishText + chs
//                }
//                
//            } else {
//                //文字
//                let text = (self.textView.text as NSString).substringWithRange(range)
//                
//                publishText = publishText + text
//            }
//        }
//        
//        return publishText
//    }
    
    //返回的方法
    @objc private func dismiss(){
        
        //注销第一响应者
        
        dismissViewControllerAnimated(true) { () -> Void in
            
        }
        
    }
    
    //自定义表情键盘的标签
    private func setupToolBar(){
        
        //修改toolBar的背景颜色.以适应美工切图的Bug
        toolBar.backgroundColor = UIColor.darkGrayColor()
        
        view.addSubview(toolBar)
        
        
        
        toolBar.snp_makeConstraints { (make) -> Void in
            make.left.bottom.right.equalTo(view)
            
            make.height.equalTo(44)
        }
        
        //添加按钮
        var items: [UIBarButtonItem] = [UIBarButtonItem]()
        
        //用一个循环来实现添加按钮 -- 需要用到图片的名字,那么用plist 或者写一个数组
        //也可以吧方法名字保存进去
        let itemSettings = [["imageName": "compose_toolbar_picture", "action": "choosePicture"],
            ["imageName": "compose_mentionbutton_background"],
            ["imageName": "compose_trendbutton_background"],
            ["imageName": "compose_emoticonbutton_background", "action": "inputEmoticon"],
            ["imageName": "compose_addbutton_background"]]
        
        //循环添加
        for itemSetting in itemSettings {
            
            //点击按钮的时候 图片要发生改变
            //按钮点击可以改变
            
            let button = UIButton(type: UIButtonType.Custom)
            
            let imageName = itemSetting["imageName"]!
            
            button.setImage(UIImage(named: imageName), forState: UIControlState.Normal)
            
            button.setImage(UIImage(named: "\(imageName)_highlighted"), forState: UIControlState.Highlighted)
            
            //添加点击方法
            if let action = itemSetting["action"] {
                
                //按钮的方法不是字符串  是Selector
                button.addTarget(self, action: Selector(action), forControlEvents: UIControlEvents.TouchUpInside)
            }
            
            //如果运行代码的时候没有试图显示
            //1.没有调用方法 ->断点实现查找Bug
            //2.没有添加
            //3.没有设置frame和约束 ->断点查找Bug
            //4.约束设置错误 - > 查看图层
            //设置button的大小
            button.sizeToFit()
            
            let item = UIBarButtonItem(customView: button)
            
            /**
            抽取代码的步骤
            1.把要抽取的代码赋值过去,缺什么,就添加到参数里
            2.把原来的代码注释掉,测试
            3.把原来的代码删掉
            */
            
            //需要把 item添加到数组里
            items.append(item)
            
            //弹簧效果 -- 如果不能确定就试试
            items.append(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil))
        }
        
        //移除最后一个弹簧
        items.removeLast()
        
        toolBar.items = items
    }
    
    
    
    //选择图片的方法
    @objc private func choosePicture(){
        
        
        let pic = UIImagePickerController()
        
        //判断相机是否可用
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
            
            
            //设置pic的类型是相机类型
            pic.sourceType = .Camera
            
            
            //跳转控制器
            presentViewController(pic, animated: true, completion: { () -> Void in
                
            })
        }
        
        //设置跳转的控制器是相册
        pic.sourceType = .PhotoLibrary
        
        
        //设置控制器为PIC的代理  必须遵守两个协议  一个是:UIImagePickerControllerDelegate 
        //一个是:UINavigationControllerDelegate
        
        //设置当前控制器为代理
        pic.delegate = self
        
        //控制器跳转
        presentViewController(pic, animated: true) { () -> Void in
            
        }
        
        
    }
    //显示表情的方法
    @objc private func inputEmoticon(){
        
        //让textView的inputView 如果为空 就默认的显示系统键盘,如果有值,就显示我们给的view
        textView.inputView == nil ? (textView.inputView = emoticonView) : (textView.inputView = nil)
        
        
        //让textView从新加载下inputView
        textView.reloadInputViews()
        
        textView.becomeFirstResponder()
    }
    
    //MARK: --通知方法
    @objc private func changeToolBarFrame(noti:NSNotification){
        
//        printLog(noti.userInfo)
        //键盘弹出的时候通知的内容
        /*
        [UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 667}, {375, 258}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {187.5, 538}, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {375, 258}}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 409}, {375, 258}}, UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardCenterBeginUserInfoKey: NSPoint: {187.5, 796}, UIKeyboardAnimationCurveUserInfoKey: 7, UIKeyboardIsLocalUserInfoKey: 1]
        
        //UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 409}, {375, 258}},
        ===============================================================*/
        //UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 667}, {375, 258}},
        
        //键盘消失的时候通知的内容
        /*
        [UIKeyboardFrameBeginUserInfoKey: NSRect: {{0, 667}, {375, 258}}, UIKeyboardCenterEndUserInfoKey: NSPoint: {187.5, 796}, UIKeyboardBoundsUserInfoKey: NSRect: {{0, 0}, {375, 258}}, UIKeyboardFrameEndUserInfoKey: NSRect: {{0, 667}, {375, 258}}, UIKeyboardAnimationDurationUserInfoKey: 0.25, UIKeyboardCenterBeginUserInfoKey: NSPoint: {187.5, 796}, UIKeyboardAnimationCurveUserInfoKey: 7, UIKeyboardIsLocalUserInfoKey: 1]
        */
        
//        noti.userInfo?[UIKeyboardFrameEndUserInfoKey]实际上是cgrectVaule的形式
        
         if let rect = noti.userInfo?[UIKeyboardFrameEndUserInfoKey]?.CGRectValue {
            
            if rect.origin.y == (kUIScreenH - rect.size.height){
                
                toolBar.snp_updateConstraints(closure: { (make) -> Void in
                    make.bottom.equalTo(self.view.snp_bottom).offset(-rect.size.height)
                })
            } else if rect.origin.y == kUIScreenH {
                toolBar.snp_updateConstraints(closure: { (make) -> Void in
                    make.bottom.equalTo(self.view.snp_bottom).offset(0)
                })
            }
            
            UIView.animateWithDuration(0.25, animations: { () -> Void in
                //重绘  约束动画必须实现的方法
                self.toolBar.layoutIfNeeded()
            })
        }
        
    }
    
    @objc private func showEmoticon(noti: NSNotification){
        
        
        if let emoticon = noti.userInfo?["key"] as? LSEmoticon{
//
//            //这里是显示默认图片和浪小花表情图片
//            if let _ = emoticon.png {
//                
//                
//                //bug
//                //后边的占位文字没有消除,
//                //图片有点大,
//                //始终都只能显示一个表情,
//                //多次点击之后变小了
//                //文字中间不能插入表情
//                //插入表情的之后 光标的位置变得不对
//                
//                
//                //记录原来的表情 因为本身是不可变的 所以前边加前缀
//                let orginal = NSMutableAttributedString(attributedString: textView.attributedText)
//                
//                //创建一个附件的实例对象
//                let attachemnt = NSTextAttachment()
//                
//                //设置属性
//                let imageName = "\(emoticon.package!)/\(emoticon.png!)"
//                
//                attachemnt.image = UIImage(named: imageName)
//                
//                //设置图片的宽高,注意TextView的font是可选的
//                let fontHeigth = textView.font!.lineHeight
//                
//                
//                attachemnt.bounds = CGRectMake(0, -4, fontHeigth, fontHeigth)
//                
//                //把附件赋值给AttributeString
//                let attribute = NSAttributedString(attachment: attachemnt)
//                
//                
//                //光标的位置
//                let range = textView.selectedRange
//                
//                //新的表情生成好之后拼接表情,然后赋值
//                //            orginal.appendAttributedString(attribute)
//                //想让他插入到光标所在的位置
//                
//                orginal.replaceCharactersInRange(range, withAttributedString: attribute)
//                //怎么改变字体大小
//                //改变图片的大小,需要设置addAttributes  还需要设置attachemnt.bounds
//                orginal.addAttributes([NSFontAttributeName:textView.font!], range: NSMakeRange(0, orginal.length))
//                //可以赋值给textView
//                textView.attributedText = orginal
//                
//                //赋值之后,改变光标的位置
//                textView.selectedRange = NSMakeRange(range.location + 1, 0)
//            }
//            
//            
//            //调用一下代理方法
//            //为什么这个方法需要写入一个!  因为现在手动调用,必须得确定这个方法实现了
//            textView.delegate?.textViewDidChange!(textView)
//
//            
//            
//            //这里是显示Emoji显示的逻辑
//            if let emoji = emoticon.emoji {
//                (textView.replaceRange(textView.selectedTextRange!, withText: emoji))
//            }
//            
//            
            textView.insertEmoticon(emoticon)
        }
        
        
    }
    
    @objc private func deleteEmoticon(noti: NSNotification){
        
    }
    
    //MARK:-- 懒!!!加载
    private lazy var textView: LSTextView = LSTextView()
    

    //底部ToolBar
    private lazy var toolBar: UIToolbar = UIToolbar()
    
    
    //中间视图
    //为防止循环引用  所以要把self变成Weak
    

    
    private lazy var chooseView:LSChooseView = {
        let choose = LSChooseView()
        
        
        //防止循环引用的问题  一般是用这种方法,  每个控制器最好都有些deinit这个方法,防止循环引用
        weak var weakSelf = self

        
        choose.closure = {[unowned self] in
            
            self.choosePicture()
        }
        
        return choose
    }()
    
    
    //懒加载表情键盘
    private lazy var emoticonView:LSEmoticonView = {
        let emot = LSEmoticonView()
        
        emot.frame = CGRectMake(0,0,kUIScreenW,216)
        
        return emot
    }()
    
    deinit{
        
        printLog("LSPublishViewCongtroller 88")
        
    }
}



extension LSPublishViewController{
    
    func textViewDidChange(textView: UITextView) {
        
        // 怎么知道有问题
        // 长度 -- 判断可以不可以实现
        if textView.hasText() {
            self.textView.holdString = ""
        } else {
            self.textView.holdString = holder
        }
        // 去重绘
        self.textView.setNeedsDisplay()
        
        navigationItem.rightBarButtonItem?.enabled = textView.hasText()
        
        
    }
    
}

extension LSPublishViewController{
    //代理方法实现
    //这个方法已经被移除,但是因为这个方法能够直接拿到Image  所以还是都喜欢用这个方法
    //这个方法一旦实现,就必须手动调用dismiss方法
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        
        chooseView.addImage(image)
        
        picker.dismissViewControllerAnimated(false) { () -> Void in
            
        }
    }
    
    
    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        
        picker.dismissViewControllerAnimated(false) { () -> Void in
            
        }
    }
}
